package com.ocom.webapi.po;


import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

@Slf4j
public class RSADemo1 {

    public static final String KEY_ALGORITHM = "RSA";

    private static final String PUBLIC_KEY = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALyRtnHHITve8tvQ4gemW+/IcRuS/uE+zCGL3SIhSgdEI3HeBgDz4MWKcheLEUqz4Yarg+P2gbOwxD9Embj7KmUCAwEAAQ==";

    private static final String PRIVATE_KEY = "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAvJG2ccchO97y29DiB6Zb78hxG5L+4T7MIYvdIiFKB0Qjcd4GAPPgxYpyF4sRSrPhhquD4/aBs7DEP0SZuPsqZQIDAQABAkAqjtxVS3Llt0iqcbdBsLsZH+zfI0rg/TJG8/EBje/OOZ9mTB9m1Bbl9O+nQTdHEVthjcbmBreYSOEdXRSx3OoBAiEA/kFiZAdisxq/amtvyD+6jh/NBehX9EbOu7TnO8zA/YECIQC93PJEB2M2qpsGWoUPv8KtXpNwBNVxLc4WfIPbxNdm5QIhAL6jYdWkoAGw9YMiqT7ZYdS8zWo3ivMywEGH47U30iCBAiBjxiBqL5eruqwNArS6OgOMKA9C5sdj2rZaisSgUSkBIQIhAMdBZtPFgELP7z4hykzfG7ACTrUM8AWTWnYMqCgDQ1P0";



    // 获取公钥
    public static PublicKey getPublicKey(String publicKeyString) throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] publicKeyByte = Base64.getDecoder().decode(publicKeyString);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyByte);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }

    // 获取私钥
    public static PrivateKey getPrivateKey(String privateKeyString) throws Exception {
        byte[] privateKeyByte = Base64.getDecoder().decode(privateKeyString);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyByte);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }


    /**
     * 公钥加密
     *
     * @param text         待加密的明文字符串
     * @param publicKeyStr 公钥
     * @return 加密后的密文
     */
    public static String encrypt(String text, String publicKeyStr) {
        try {
            log.info("明文字符串为:[{}]", text);
            Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKeyStr));
            byte[] tempBytes = cipher.doFinal(text.getBytes("UTF-8"));
            return Base64.getEncoder().encodeToString(tempBytes);
        } catch (Exception e) {
            throw new RuntimeException("加密字符串[" + text + "]时遇到异常", e);
        }
    }

    /**
     * 私钥解密
     *
     * @param secretText    待解密的密文字符串
     * @param privateKeyStr 私钥
     * @return 解密后的明文
     */
    public static String decrypt(String secretText, String privateKeyStr) {
        try {
            // 生成私钥
            Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKeyStr));
            // 密文解码
            byte[] secretTextDecoded = Base64.getDecoder().decode(secretText.getBytes("UTF-8"));
            byte[] tempBytes = cipher.doFinal(secretTextDecoded);
            return new String(tempBytes);
        } catch (Exception e) {
            throw new RuntimeException("解密字符串[" + secretText + "]时遇到异常", e);
        }
    }

    public static void main(String[] args) throws Exception {
        String cipherText;
        // 原始明文
        String code = "userkey=111";

        log.info("公钥:[{}]，长度:[{}]", PUBLIC_KEY, PUBLIC_KEY.length());
        log.info("私钥:[{}]，长度:[{}]", PRIVATE_KEY, PRIVATE_KEY.length());

        // 加密用户标识
        cipherText = encrypt(code, PUBLIC_KEY);

        log.info("加密后的密文:{}，长度:{}]", cipherText, cipherText.length());
        String url = "https://home.firefoxchina.cn?"+cipherText;
        String encode = URLEncoder.encode(url, "UTF-8");
        log.info("传过去的url:{}", encode);
        // 解密
        String decode = URLDecoder.decode(encode, "UTF-8");
        log.info("接收后处理url:{}", decode);
        String text = decode.split("\\?")[1];
        String plainText = decrypt(text, PRIVATE_KEY);
        log.info("解密后明文:{}", plainText);
    }
}



